package com.example.test06thread.test.juc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: fxy
 * @Date: 2022/04/15/15:47
 * @Description:
 *        如何精准唤醒和通知线程，从而按照自己的意愿进行执行
 * 	Condition：同步监视器
 * 	使用Condition实现指定唤醒功能
 */
public class ProConJuc {
    public static void main(String[] args) {
        PCJ pc = new PCJ();
        new Thread(()->{for (int i=0;i<10;i++){pc.partA();}},"A").start();
        new Thread(()->{for (int i=0;i<10;i++){pc.partB();}},"B").start();
        new Thread(()->{for (int i=0;i<10;i++){pc.partC();}},"C").start();

    }
}

class PCJ {
    private int number = 0;

    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    public void partA(){
        lock.lock();
        try {
            //业务：判断等待-》执行-》通知
            while (number!=0){
                condition1.await();
            }
            //业务
            System.out.println(Thread.currentThread().getName()+"线程执行了========"+number);
            //唤醒，指定唤醒:condition2=>B
            number=1;
            condition2.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void partB(){
        lock.lock();
        try {
            //业务：判断等待-》执行-》通知
            while (number!=1){
                condition2.await();
            }
            //业务
            System.out.println(Thread.currentThread().getName()+"线程执行了========"+number);
            //唤醒，指定唤醒:condition3=>C
            number=2;
            condition3.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void partC(){
        lock.lock();
        try {
            //业务：判断等待-》执行-》通知
            while (number!=2){
                condition3.await();
            }
            //业务
            System.out.println(Thread.currentThread().getName()+"线程执行了========"+number);
            //唤醒，指定唤醒:condition1=>A
            number=0;
            condition1.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}
